using System;
using System.Text;
using System.Xml;
using System.Collections;

using gudusoft.gsqlparser;
using gudusoft.gsqlparser.Units;


namespace xmloutput
{
    class commonstmt
    {
        public static string TSqlStatementXml(TCustomSqlStatement pSql)
        {
            
            switch (pSql.SqlStatementType)
            {
                case TSqlStatementType.sstSelect:
                    return TSelectSqlStatementXml((TSelectSqlStatement)pSql);
                case TSqlStatementType.sstDelete:
                    return TDeleteSqlStatementXml((TDeleteSqlStatement)pSql);
                case TSqlStatementType.sstInsert:
                    return TInsertSqlStatementXml((TInsertSqlStatement)pSql);
                case TSqlStatementType.sstUpdate:
                    return TUpdateSqlStatementXml((TUpdateSqlStatement)pSql);
                case TSqlStatementType.sstCreateTable:
                    return TCreateTableSqlStatementXml((TCreateTableSqlStatement)pSql);
                case TSqlStatementType.sstCreateView:
                    return TCreateViewSqlStatementXml((TCreateViewSqlStatement)pSql);
                case TSqlStatementType.sstMssqlCreateFunction:
                    return sqlserverstmt.TMssqlCreateFunctionXml((TMssqlCreateFunction)pSql);
                case TSqlStatementType.sstMssqlCreateProcedure:
                    return sqlserverstmt.TMssqlCreateProcedureXml((TMssqlCreateProcedure)pSql);
                case TSqlStatementType.sstMssqlCreateTrigger:
                    return sqlserverstmt.TMssqlCreateTriggerXml((TMssqlCreateTrigger)pSql);
                case TSqlStatementType.sstMssqlIf:
                    return sqlserverstmt.TMssqlIfElseXml((TMssqlIfElse)pSql);
                case TSqlStatementType.sstMssqlBlock:
                    return sqlserverstmt.TMssqlBlockXml((TMssqlBlock)pSql);
                case TSqlStatementType.sstMssqlDeclare:
                    return sqlserverstmt.TMssqlDeclareXml((TMssqlDeclare)pSql);
                case TSqlStatementType.sstMssqlSet:
                    return sqlserverstmt.TMssqlSetXml((TMssqlSet)pSql);
                case TSqlStatementType.sstMssqlExec:
                    return sqlserverstmt.TMssqlExecuteXml((TMssqlExecute)pSql);
                case TSqlStatementType.sstMssqlBeginTran:
                    return sqlserverstmt.TMssqlBeginTranXml((TMssqlBeginTran)pSql);
                case TSqlStatementType.sstMssqlCommit:
                    return sqlserverstmt.TMssqlCommitXml((TMssqlCommit)pSql);
                case TSqlStatementType.sstMssqlRollback:
                    return sqlserverstmt.TMssqlRollbackXml((TMssqlRollback)pSql);
                case TSqlStatementType.sstMssqlDeallocate:
                    return sqlserverstmt.TMssqlDeallocateXml((TMssqlDeallocate)pSql);
                case TSqlStatementType.sstMssqlReturn:
                    return sqlserverstmt.TMssqlReturnXml((TMssqlReturn)pSql);
                default:
                    XmlWriterSettings settings = new XmlWriterSettings();
                    settings.OmitXmlDeclaration = true;
                    settings.Indent = true;
                    settings.IndentChars = ("    ");

                    StringBuilder XmlText = new StringBuilder();
                    using (XmlWriter writer = XmlWriter.Create(XmlText, settings))
                    {
                        // Write XML data.
                        writer.WriteStartElement("sqlstatement");
                        writer.WriteAttributeString("type", pSql.SqlStatementType.ToString());
                        writer.WriteRaw(pSql.AsText);
                        writer.WriteEndElement();
                        writer.Flush();
                    }
                    return XmlText.ToString();
            }
        }

        public static string TCreateTableSqlStatementXml(TCreateTableSqlStatement pSql)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            settings.Indent = true;
            settings.IndentChars = ("    ");

            StringBuilder XmlText = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(XmlText, settings))
            {
                // Write XML data.
                writer.WriteStartElement("sqlstatement");
                writer.WriteAttributeString("type", pSql.SqlStatementType.ToString());

                writer.WriteStartElement("tablename");
                writer.WriteRaw(basicnodexml.TLz_AttrXml(pSql.Table.TableAttr));
                writer.WriteEndElement();

                writer.WriteRaw(basicnodexml.TLzFieldListXml(pSql.Table.Fields));

                if (pSql.Table.TableConstraints.Count() > 0)
                {
                    writer.WriteRaw(basicnodexml.TLzConstraintListXml(pSql.Table.TableConstraints));
                }
                writer.WriteEndElement();
            }
            return XmlText.ToString();
        }

        public static string TStmtListXml(TLzStatementList pList)
        {
            StringBuilder stmts = new StringBuilder();

            foreach (TCustomSqlStatement sql in pList)
            {
                stmts.Append(TSqlStatementXml(sql));
            }

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            settings.Indent = true;
            settings.IndentChars = ("    ");

            StringBuilder XmlText = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(XmlText, settings))
            {
                // Write XML data.
                writer.WriteStartElement("sqlstatements");
                writer.WriteRaw(stmts.ToString());
                writer.WriteEndElement();
            }
            return XmlText.ToString();

        }

        public static string TCreateViewSqlStatementXml(TCreateViewSqlStatement pSql)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            settings.Indent = true;
            settings.IndentChars = ("    ");

            StringBuilder XmlText = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(XmlText, settings))
            {
                // Write XML data.
                writer.WriteStartElement("sqlstatement");
                writer.WriteAttributeString("type", pSql.SqlStatementType.ToString());
                
                writer.WriteStartElement("viewname");
                writer.WriteRaw(pSql.ViewName);
                writer.WriteEndElement();

                if (pSql.column_list != null)
                {
                    writer.WriteStartElement("column_list");
                    for (int i = 0; i < pSql.column_list.Count(); i++)
                    {
                        writer.WriteStartElement("column_name");
                        writer.WriteRaw(basicnodexml.TLz_AttrXml((TLz_Attr)(pSql.column_list[i])));
                        writer.WriteEndElement();
                    }
                    
                    writer.WriteEndElement();
                }

                writer.WriteRaw("\n");

                writer.WriteRaw(commonstmt.TSelectSqlStatementXml(pSql.SubQuery));

                writer.WriteRaw("\n");

                writer.WriteEndElement();
                writer.Flush();

            }

            return XmlText.ToString();

        }

        public static string TSelectSqlStatementXml(TSelectSqlStatement pSql)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            settings.Indent = true;
            settings.IndentChars = ("    ");

            StringBuilder XmlText = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(XmlText, settings))
            {
                // Write XML data.
                writer.WriteStartElement("sqlstatement");
                writer.WriteAttributeString("type", pSql.SqlStatementType.ToString());
                writer.WriteAttributeString("settype", pSql.SelectSetType.ToString());
                if (pSql.cte != null)
                {
                    writer.WriteStartElement("ctes");
                    for (int i=0; i < pSql.cte.ctes.Count(); i++)
                    {
                        TCommonTableExpression cte = (TCommonTableExpression)(pSql.cte.ctes[i]);
                        writer.WriteRaw(basicnodexml.TCommonTableExpressionXml(cte));
                    }
                    writer.WriteEndElement();
                }
                if (pSql.SelectSetType != TSelectSetType.sltNone)
                {
                    writer.WriteRaw(TSelectSqlStatementXml((TSelectSqlStatement)(pSql.LeftStmt)));
                    writer.WriteRaw(TSelectSqlStatementXml((TSelectSqlStatement)(pSql.RightStmt)));
                    if (pSql.SortClause != null)
                    {
                        writer.WriteStartElement("orderbylist");
                        foreach (TLzOrderBy ob in pSql.SortClause)
                        {
                            writer.WriteRaw(basicnodexml.TLzOrderByXml(ob));
                        }
                        writer.WriteEndElement();
                    }
                }
                else
                {
                    if (pSql.SelectDistinct != null)
                    {
                        writer.WriteStartElement(pSql.SelectDistinct.GetType().Name);
                        writer.WriteAttributeString("value", pSql.SelectDistinct.DistinctType.ToString());
                        writer.WriteEndElement();

                    }

                    if (pSql.topclause != null)
                    {
                        writer.WriteRaw(basicnodexml.TLzTopClauseXml(pSql.topclause));
                    }

                    writer.WriteRaw(basicnodexml.TLzFieldListXml(pSql.Fields));

                    if (pSql.IntoClause != null)
                    {
                        writer.WriteStartElement("intoclause");
                        writer.WriteRaw(basicnodexml.TLzCustomExpressionXml(pSql.IntoClause));
                        writer.WriteEndElement();
                    }

                    writer.WriteRaw(basicnodexml.TLzJoinListXml(pSql.JoinTables));

                    if (pSql.WhereClause != null)
                    {
                        writer.WriteStartElement("whereclause");
                        writer.WriteRaw(basicnodexml.TLzCustomExpressionXml(pSql.WhereClause));
                        writer.WriteEndElement();
                        
                    }

                    if (pSql.GroupbyClause != null)
                    {
                        //writer.WriteStartElement("groupbyclause");
                        writer.WriteRaw(basicnodexml.TLzGroupByXml(pSql.GroupbyClause));
                        //writer.WriteEndElement();
                    }

                    if (pSql.HavingClause != null)
                    {
                        writer.WriteStartElement("havingclause");
                        writer.WriteRaw(basicnodexml.TLzCustomExpressionXml((TLzCustomExpression)(pSql.HavingClause)));
                        writer.WriteEndElement();
                    }

                    if (pSql.SortClause != null)
                    {
                        writer.WriteStartElement("orderbylist");
                        foreach (TLzOrderBy ob in pSql.SortClause)
                        {
                            writer.WriteRaw(basicnodexml.TLzOrderByXml(ob));
                        }
                        writer.WriteEndElement();
                    }

                }
                writer.WriteEndElement();
                writer.Flush();
            }
            return XmlText.ToString();
        }

        public static string TDeleteSqlStatementXml(TDeleteSqlStatement pSql)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            settings.Indent = true;
            settings.IndentChars = ("    ");

            StringBuilder XmlText = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(XmlText, settings))
            {
                // Write XML data.
                writer.WriteStartElement("sqlstatement");
                writer.WriteAttributeString("type", pSql.SqlStatementType.ToString());

                if (pSql.cte != null)
                {
                    writer.WriteStartElement("ctes");
                    for (int i = 0; i < pSql.cte.ctes.Count(); i++)
                    {
                        TCommonTableExpression cte = (TCommonTableExpression)(pSql.cte.ctes[i]);
                        writer.WriteRaw(basicnodexml.TCommonTableExpressionXml(cte));
                    }
                    writer.WriteEndElement();
                }

                if (pSql.TopClause != null)
                {
                    writer.WriteRaw(basicnodexml.TLzTopClauseXml(pSql.TopClause));
                }

                if (pSql.DeletedTables.Count() > 0)
                {
                    writer.WriteRaw(basicnodexml.TLzJoinListXml(pSql.DeletedTables));
                }
                else if (pSql.Table != null)
                {
                    writer.WriteRaw(basicnodexml.TLzTableXml(pSql.Table));
                }

                if (pSql.OutputClause != null)
                {
                    writer.WriteRaw(sqlserverstmt.TMssqlOutputClauseXml((TMssqlOutputClause)pSql.OutputClause));
                }

                if (pSql.JoinTables.Count() > 0)
                {
                    writer.WriteRaw(basicnodexml.TLzJoinListXml(pSql.JoinTables));
                }


                if (pSql.Table.Fields.Count() > 0)
                { //db2 only
                    writer.WriteRaw(basicnodexml.TLzFieldListXml(pSql.Table.Fields));
                }

                if (pSql.WhereClause != null)
                {
                    writer.WriteStartElement("whereclause");
                    writer.WriteRaw(basicnodexml.TLzCustomExpressionXml(pSql.WhereClause));
                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
            }
            return XmlText.ToString();
        }

        public static string TInsertSqlStatementXml(TInsertSqlStatement pSql)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            settings.Indent = true;
            settings.IndentChars = ("    ");

            StringBuilder XmlText = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(XmlText, settings))
            {
                // Write XML data.
                writer.WriteStartElement("sqlstatement");
                writer.WriteAttributeString("type", pSql.SqlStatementType.ToString());

                if (pSql.cte != null)
                {
                    writer.WriteStartElement("ctes");
                    for (int i = 0; i < pSql.cte.ctes.Count(); i++)
                    {
                        TCommonTableExpression cte = (TCommonTableExpression)(pSql.cte.ctes[i]);
                        writer.WriteRaw(basicnodexml.TCommonTableExpressionXml(cte));
                    }
                    writer.WriteEndElement();
                }

                if (pSql.TopClause != null)
                {
                    writer.WriteRaw(basicnodexml.TLzTopClauseXml(pSql.TopClause));
                }

                writer.WriteRaw(basicnodexml.TLzTableXml(pSql.Table));

                if (pSql.Fields.Count() > 0)
                {
                    writer.WriteStartElement("columns");
                    writer.WriteRaw(basicnodexml.TLzFieldListXml(pSql.Fields));
                    writer.WriteEndElement();
                }

                if (pSql.OutputClause != null)
                {
                    writer.WriteRaw(sqlserverstmt.TMssqlOutputClauseXml((TMssqlOutputClause)pSql.OutputClause));
                }

                writer.WriteStartElement("values");
                writer.WriteAttributeString("valtype", pSql.ValueType.ToString());

                switch (pSql.ValueType)
                {
                    case TInsertValueType.ivtValue:
                        if (pSql.MultiValues.Count() > 0)
                        {
                            for (int i = 0; i < pSql.MultiValues.Count(); i++)
                            {
                                TLzFieldList fieldlist = (TLzFieldList)pSql.MultiValues[i];
                                writer.WriteRaw(basicnodexml.TLzFieldListXml(fieldlist));
                            }
                        }
                        if (pSql.Values.Count() > 0)
                        {
                            writer.WriteRaw(basicnodexml.TLzFieldListXml(pSql.Values));
                        }
                        break;
                    case TInsertValueType.ivtSubquery:
                        writer.WriteRaw(TSelectSqlStatementXml(pSql.subquery));
                        break;
                    default:
                        break;
                }
                writer.WriteEndElement();

                writer.WriteEndElement();
                writer.Flush();
            }
            return XmlText.ToString();
        }

        public static string TUpdateSqlStatementXml(TUpdateSqlStatement pSql)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            settings.Indent = true;
            settings.IndentChars = ("    ");

            StringBuilder XmlText = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(XmlText, settings))
            {
                // Write XML data.
                writer.WriteStartElement("sqlstatement");
                writer.WriteAttributeString("type", pSql.SqlStatementType.ToString());

                if (pSql.cte != null)
                {
                    writer.WriteStartElement("ctes");
                    for (int i = 0; i < pSql.cte.ctes.Count(); i++)
                    {
                        TCommonTableExpression cte = (TCommonTableExpression)(pSql.cte.ctes[i]);
                        writer.WriteRaw(basicnodexml.TCommonTableExpressionXml(cte));
                    }
                    writer.WriteEndElement();
                }

                if (pSql.TopClause != null)
                {
                    writer.WriteRaw(basicnodexml.TLzTopClauseXml(pSql.TopClause));
                }

                if (pSql.UpdateTables.Count() > 0)
                {
                    writer.WriteRaw(basicnodexml.TLzJoinListXml(pSql.UpdateTables));
                }
                else
                {
                    writer.WriteRaw(basicnodexml.TLzTableXml(pSql.Table));
                }

                writer.WriteStartElement("setclause");
                writer.WriteRaw(basicnodexml.TLzFieldListXml(pSql.Fields));
                writer.WriteEndElement();

                if (pSql.OutputClause != null)
                {
                    writer.WriteRaw(sqlserverstmt.TMssqlOutputClauseXml((TMssqlOutputClause)pSql.OutputClause));
                }

                if (pSql.JoinTables.Count() > 0)
                {
                    writer.WriteRaw(basicnodexml.TLzJoinListXml(pSql.JoinTables));
                }

                if (pSql.WhereClause != null)
                {
                    writer.WriteStartElement("whereclause");
                    writer.WriteRaw(basicnodexml.TLzCustomExpressionXml(pSql.WhereClause));
                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
                writer.Flush();
            }
            return XmlText.ToString();
        }
    }
}
